package org.spiderflow.mongodb.web;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spiderflow.core.service.SpArticleService;
import org.spiderflow.mongodb.model.FileDocument;
import org.spiderflow.mongodb.model.ResponseModel;
import org.spiderflow.mongodb.service.IFileService;
import org.spiderflow.utils.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

//@CrossOrigin(origins = "*", maxAge = 3600)
//@Controller
//@RequestMapping("/mongodb")
public class MongoFileController {

  Logger logger = LoggerFactory.getLogger(MongoFileController.class);

  @Autowired
  private IFileService fileService;

  @Autowired
  private SpArticleService spArticleService;

  @Autowired
  CommonsMultipartResolver multipartResolver;

  @RequestMapping(value = "/index", method = RequestMethod.GET)
//  @ResponseBody
  public String index(String alias, Model model) {
    // 展示最新二十条数据
    model.addAttribute("files", fileService.listFilesByPage(alias, 0, 20));
    model.addAttribute("alias", alias);
    return "mongo";
  }

  /**
   * 上传文件列表
   */
  @RequestMapping(value = "/list", method = RequestMethod.GET)
  @ResponseBody
  public List<FileDocument> list(String alias, int pageIndex, int pageSize) {
    return fileService.listFilesByPage(alias, pageIndex, pageSize);
  }

  /**
   * 获取文件片信息
   */
  @RequestMapping(value = "/files/{id}", method = RequestMethod.GET)
  @ResponseBody
  public ResponseEntity<Object> serveFile(@RequestParam("alias") String alias,
      @PathVariable("id") String id)
      throws UnsupportedEncodingException {

    Optional<FileDocument> file = fileService.getFileById(alias, id);

    if (file.isPresent()) {
      return ResponseEntity.ok()
          .header(HttpHeaders.CONTENT_DISPOSITION,
              "attachment; fileName=" + new String(file.get().getName().getBytes("utf-8"),
                  "ISO-8859-1"))
          .header(HttpHeaders.CONTENT_TYPE, "application/octet-stream")
          .header(HttpHeaders.CONTENT_LENGTH, file.get().getSize() + "")
          .header("Connection", "close")
          .body(file.get().getContent());
    } else {
      return ResponseEntity.status(HttpStatus.NOT_FOUND).body("File was not fount");
    }

  }

  /**
   * 在线显示文件
   *
   * @param id 文件id
   */
  @RequestMapping(value = "/view/{id}", method = RequestMethod.GET)
  @ResponseBody
  public ResponseEntity<Object> serveFileOnline(@RequestParam("alias") String alias,
      @PathVariable("id") String id) {
    Optional<FileDocument> file = fileService.getFileById(alias, id);
    if (file.isPresent()) {
      return ResponseEntity.ok()
          .header(HttpHeaders.CONTENT_DISPOSITION, "fileName=" + file.get().getName())
          .header(HttpHeaders.CONTENT_TYPE, file.get().getContentType())
          .header(HttpHeaders.CONTENT_LENGTH, file.get().getSize() + "")
          .header("Connection", "close")
          .body(file.get().getContent());
    } else {
      return ResponseEntity.status(HttpStatus.NOT_FOUND).body("File was not found");
    }
  }

  /**
   * 下载文件
   */
  @RequestMapping(value = "/{id}", method = RequestMethod.GET)
  @ResponseBody
  public ResponseEntity<Object> downloadFileById(@RequestParam("alias") String alias,
      @PathVariable("id") String id)
      throws UnsupportedEncodingException {
    Optional<FileDocument> file = fileService.getFileById(alias, id);
    if (file.isPresent()) {
      return ResponseEntity.ok()
          .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; fileName=" + URLEncoder
              .encode(file.get().getName(), "utf-8"))
          .header(HttpHeaders.CONTENT_TYPE, "application/octet-stream")
          .header(HttpHeaders.CONTENT_LENGTH, file.get().getSize() + "")
          .header("Connection", "close")
          .body(file.get().getContent());
    } else {
      return ResponseEntity.status(HttpStatus.NOT_FOUND).body("File was not found");
    }
  }

  @RequestMapping(value = "/upload", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
  @ResponseBody
  public ResponseModel formUpload(HttpServletRequest request,
      @RequestParam("alias") String alias) {
    ResponseModel model = ResponseModel.getInstance();

    List<MultipartFile> fileList = new ArrayList<>();
    //创建一个通用的多部分解析器
//    CommonsMultipartResolver multipartResolver =
//        new CommonsMultipartResolver(request.getSession().getServletContext());
    //判断 request 是否有文件上传,即多部分请求
    if (multipartResolver.isMultipart(request)) {
      //转换成多部分request
      MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
      //取得request中的所有文件名
      fileList = multiRequest.getFiles("file");
      if (fileList == null || fileList.size() <= 0) {
        model.setMessage("请传入文件");
        return model;
      }

      StringBuilder sqls = new StringBuilder();

      for (MultipartFile file : fileList) {
        try {
          if (file != null && !file.isEmpty()) {
            String fileMd5 = MD5Util.getMD5(file.getInputStream());
            FileDocument fileDocument = fileService.saveFile(alias, fileMd5, file);
            String fileName = file.getOriginalFilename();
            logger.info("文件名称：{}，文件ID：{}", fileName, fileDocument.getId());

            StringBuffer updateSql = new StringBuffer("update sp_article set file_id = '");
            updateSql.append(fileDocument.getId())
                .append("' where file_name = '")
                .append(fileName)
                .append("';");

            sqls.append(updateSql.toString());
            //spArticleService.updateFileIdByName(fileDocument.getId(), fileName);
          }
        } catch (Exception e) {
          logger.error("上传mongo异常", e);
        }
      }
      logger.info(sqls.toString());
    }

    model.setCode(ResponseModel.Success);
    model.setMessage("上传成功");
    return model;
  }

  /**
   * 表单上传文件 当数据库中存在该md5值时，可以实现秒传功能
   *
   * @param file 文件
   */
  @RequestMapping(value = "/upload1", method = RequestMethod.POST)
  @ResponseBody
  public ResponseModel formUpload1(@RequestParam("alias") String alias,
      @RequestParam("file") MultipartFile file) {
    ResponseModel model = ResponseModel.getInstance();
    try {
      if (file != null && !file.isEmpty()) {
        String fileMd5 = MD5Util.getMD5(file.getInputStream());
        FileDocument fileDocument = fileService.saveFile(alias, fileMd5, file);
        String fileName = file.getOriginalFilename();
        logger.info("文件名称：{}，文件ID：{}", fileName, fileDocument.getId());

        StringBuffer updateSql = new StringBuffer("update sp_article set file_id = '");
        updateSql.append(fileDocument.getId())
            .append("' where file_name = '")
            .append(fileName)
            .append("';");
        logger.info(updateSql.toString());

//        spArticleService.updateFileIdByName(fileDocument.getId(), fileName);

        model.setData(fileDocument.getId());
        model.setCode(ResponseModel.Success);
        model.setMessage("上传成功");
      } else {
        model.setMessage("请传入文件");
      }
    } catch (IOException | NoSuchAlgorithmException ex) {
      logger.error("上传mongo异常", ex);
      model.setMessage(ex.getMessage());
    }
    return model;
  }

  /**
   * 删除附件
   */
  @RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)
  @ResponseBody
  public ResponseModel deleteFileByGetMethod(@RequestParam("alias") String alias,
      @PathVariable("id") String id) {
    ResponseModel model = ResponseModel.getInstance();
    if (!StringUtils.isEmpty(id)) {
      fileService.removeFile(alias, id, true);
      model.setCode(ResponseModel.Success);
      model.setMessage("删除成功");
    } else {
      model.setMessage("请传入文件id");
    }
    return model;
  }

  //将指定路径下的文件存储到mogodb的alias库中
  @RequestMapping(value = "/bthUpload", method = RequestMethod.POST)
  @ResponseBody
  public ResponseModel bthUpload(String path, String alias) {
//    String path = "D:\\spider\\pdf";
    ResponseModel model = ResponseModel.getInstance();
    List<MultipartFile> fileList = new ArrayList<>();
    StringBuilder sqls = new StringBuilder();

    List<FileDocument> allFileDocuments = fileService.listFilesByPage(alias, 1, 10000000);

    File dir = new File(path);
    File[] files = dir.listFiles();
    for (File file : files) {
      if (file.isDirectory()) {
        continue;
      }

      try {
        FileInputStream inputStream = new FileInputStream(file);

        String contentType = "application/pdf";
        String name = file.getName();
        String suffix = name.split("\\.")[1];
        if (!"pdf".equals(suffix)) {
          contentType = "";
        }

        MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getName(),
            contentType, inputStream);

        fileList.add(multipartFile);
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }

    for (MultipartFile file : fileList) {
      try {
        if (file != null && !file.isEmpty()) {
          String fileMd5 = MD5Util.getMD5(file.getInputStream());



          FileDocument fileDocument = fileService.saveFile(alias, fileMd5, file);
          String fileName = file.getOriginalFilename();
          logger.info("文件名称：" + fileName + "，文件ID：" + fileDocument.getId());

          StringBuffer updateSql = new StringBuffer("update sp_article set file_id = '");
          updateSql.append(fileDocument.getId())
              .append("' where file_name = '")
              .append(fileName)
              .append("';");

          sqls.append(updateSql.toString());
        }
      } catch (Exception e) {
        logger.error("上传mongo异常", e);
      }
    }
    logger.info(sqls.toString());

    model.setCode(ResponseModel.Success);
    model.setMessage("上传成功");
    return model;
  }


}